#include <iostream>

#if 0
    class Test
    {
    public:
        // 构造函数本质上还是普通函数
        // 我们已经把构造函数作为初始化所有变量的函数了
        // const修饰的成员变量没有办法在构造函数内部进行初始化赋值
        // 为了解决这个问题，我们引入初始化列表
        // 核心区别在于：初始化列表是在对象创建时初始化成员变量（成员变量的初始化发生在构造函数体执行之前），而构造函数内部只能执行赋值操作（而不是初始化）。
        Test()
        {
            a = 0;  // 进行初始化
        }

        void show()
        {
            std::cout<<this->a<<std::endl;
        }

    private:
        const int a;
    };

    int main()
    {
        Test t;
        t.show();
        return 0;
    }
#endif

#if 1
    class Test
    {
    public:
        // 初始化列表
        // const变量必须在初始化列表中进行初始化，普通变量也可以
        // Test():a(0),b(10)
        // {
            
        // }

        Test(int b):a(0),b(b)   // 外面的b是正体，里面的b是斜体，也就是说初始化列表能自动识别成员变量和形参变量，在外面的一定是成员变量，在里面的一定是形参变量
        {

        }

        void show()
        {
            std::cout<<this->a<<" "<<this->b<<std::endl;
        }

    private:
        const int a;
        int b;
    };

    int main()
    {
        Test t(1);
        t.show();
        return 0;
    }
#endif

/* 初始化列表适用于 必须在对象创建时完成初始化的成员变量，主要包括以下几种情况：
    1. const 成员变量：const变量必须在初始化列表中初始化，因为它不能被赋值。
    2. 引用（&）成员变量：引用必须在声明时绑定到一个对象，因此只能通过初始化列表初始化。
    3. 没有默认构造函数的对象成员：如果成员变量是某个类的对象，而该类没有默认构造函数，就必须在初始化列表中提供初始值。
    4. 父类构造函数（基类）：在派生类中，必须使用初始化列表调用基类的构造函数，否则会调用基类的默认构造函数。
    5. 需要提高性能时（避免额外的赋值操作）：初始化列表能 直接初始化成员变量，避免先调用默认构造，再赋值，提高效率。 */

